﻿
namespace RIA.Web.Services
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.ComponentModel.DataAnnotations;
	using System.Data;
	using System.Linq;
	using System.ServiceModel.DomainServices.EntityFramework;
	using System.ServiceModel.DomainServices.Hosting;
	using System.ServiceModel.DomainServices.Server;
	using RIA.Web.Models;
	using System.Diagnostics;


	// Implements application logic using the NorthwindEntities context.
	// TODO: Add your application logic to these methods or in additional methods.
	// TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
	// Also consider adding roles to restrict access as appropriate.
	[EnableClientAccess()]
	//[RequiresAuthentication]
	//[RequiresRole("Admin")]
	public class NorthWindService : LinqToEntitiesDomainService<NorthwindEntities>
	{
		[Query(HasSideEffects=false, IsComposable=false)]
		public Customer GetAdminCustomer(string id)
		{
			//也可以返回特定的类型
			return (from cust in this.ObjectContext.Customers where cust.CustomerID==id select cust).First();
		}

		[Query]
		public IEnumerable<Customer> GetCustomersStartWith(string text)
		{
			return from cust in this.ObjectContext.Customers
				   where cust.City.StartsWith(text)
				   select cust;
		}
		
		//[Ignore()]
		[Update(UsingCustomMethod = true)]
		public void SpecialCascadedUpdate(Customer cust) 
		{
			Debug.WriteLine("update");
		}

		[Ignore()]
		public void UpdateMyCustomer(Customer cust)
		{
			Debug.WriteLine("update");
		}

		[Invoke()]
		public int CalculateVacationBonus(DateTime hireDate)
		{
			int vacationBonus;
			DateTime today = DateTime.Today;
			int yearsInService = today.Year - hireDate.Year;
			if (hireDate.AddYears(yearsInService) > today)
				yearsInService--;
			if (yearsInService < 5)
				vacationBonus = 10;
			else
				vacationBonus = 20;
			return vacationBonus;
		}

		// TODO:
		// Consider constraining the results of your query method.  If you need additional input you can
		// add parameters to this method or create additional query methods with different names.
		// To support paging you will need to add ordering to the 'Customers' query.
		[Query(IsDefault = true)]
		public IQueryable<Customer> GetCustomers()
		{
			return this.ObjectContext.Customers;
		}

		public void InsertCustomer(Customer customer)
		{
			if ((customer.EntityState != EntityState.Detached))
			{
				this.ObjectContext.ObjectStateManager.ChangeObjectState(customer, EntityState.Added);
			}
			else
			{
				this.ObjectContext.Customers.AddObject(customer);
			}
		}

		//[Ignore()]
		public void UpdateCustomer(Customer currentCustomer)
		{
			this.ObjectContext.Customers.AttachAsModified(currentCustomer, this.ChangeSet.GetOriginal(currentCustomer));
		}

		public void DeleteCustomer(Customer customer)
		{
			if ((customer.EntityState == EntityState.Detached))
			{
				this.ObjectContext.Customers.Attach(customer);
			}
			this.ObjectContext.Customers.DeleteObject(customer);
		}

		// TODO:
		// Consider constraining the results of your query method.  If you need additional input you can
		// add parameters to this method or create additional query methods with different names.
		// To support paging you will need to add ordering to the 'Products' query.
		[Query(IsDefault = true)]
		public IQueryable<Product> GetProducts()
		{
			return this.ObjectContext.Products;
		}

		public void InsertProduct(Product product)
		{
			if ((product.EntityState != EntityState.Detached))
			{
				this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
			}
			else
			{
				this.ObjectContext.Products.AddObject(product);
			}
		}

		public void UpdateProduct(Product currentProduct)
		{
			this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
		}

		public void DeleteProduct(Product product)
		{
			if ((product.EntityState == EntityState.Detached))
			{
				this.ObjectContext.Products.Attach(product);
			}
			this.ObjectContext.Products.DeleteObject(product);
		}

		// TODO:
		// Consider constraining the results of your query method.  If you need additional input you can
		// add parameters to this method or create additional query methods with different names.
		// To support paging you will need to add ordering to the 'Suppliers' query.
		[Query(IsDefault = true)]
		public IQueryable<Supplier> GetSuppliers()
		{
			return this.ObjectContext.Suppliers;
		}

		public void InsertSupplier(Supplier supplier)
		{
			if ((supplier.EntityState != EntityState.Detached))
			{
				this.ObjectContext.ObjectStateManager.ChangeObjectState(supplier, EntityState.Added);
			}
			else
			{
				this.ObjectContext.Suppliers.AddObject(supplier);
			}
		}

		public void UpdateSupplier(Supplier currentSupplier)
		{
			this.ObjectContext.Suppliers.AttachAsModified(currentSupplier, this.ChangeSet.GetOriginal(currentSupplier));
		}

		public void DeleteSupplier(Supplier supplier)
		{
			if ((supplier.EntityState == EntityState.Detached))
			{
				this.ObjectContext.Suppliers.Attach(supplier);
			}
			this.ObjectContext.Suppliers.DeleteObject(supplier);
		}
	}
}


